package edu.hawaii.halealohacli;

import java.util.List;
import javax.xml.datatype.XMLGregorianCalendar;
import org.wattdepot.client.WattDepotClient;
import org.wattdepot.resource.source.jaxb.Source;
import org.wattdepot.util.tstamp.Tstamp;

  
  /**
   * SetBaseline class that returns the energy used.
   * per hour in a 24 hour period on the date (yyyy-mm-dd) 
   * 
   * @author Jordan Do
   * 
   */

  public class SetBaseline {
    String tower = null;
    String date = null;
    WattDepotClient client;
    //HashMap<String, double[]> baseList = new HashMap<String, double[]>();
  
    /**
     * Default constructor for setBaseline.
     * 
     * @param tower the tower to query.
     * @param client the WattDepot client.
     */
    public SetBaseline(String tower, WattDepotClient client) {
      this.tower = tower;
      this.client = client;
    }
  /**
   * Constructor when a date is given.
   * 
   * @param tower the tower to query.
   * @param date the date to set the baseline.
   * @param client the WattDepot client.
   */
    public SetBaseline(String tower, String date, WattDepotClient client) {
      this.tower = tower;
      this.date = date;
      this.client = client;
    }
    /**
     * Simple accessor method to get the value of tower or the tower name.
     * 
     * @return Returns the value of tower or tower name.
     */
    public String getTower() {
      return this.tower;
    }
  
    /**
     * Simple accessor method to get the value of date.
     * 
     * @return Returns the value of date.
     */
    public String getDate() {
      return this.date;
    }
  
    /**
     * Checks that date is valid before running real set-baseline.
     * 
     * @throws Exception If error occurs while running method.
     * @return a boolean, true if command is successful.
     */
    public boolean run() throws Exception {
      if (date == null) {
        return true;
      }
      else {
        XMLGregorianCalendar cal = Tstamp.makeTimestamp(date);
        XMLGregorianCalendar current = Tstamp.makeTimestamp();
        current = Tstamp.incrementDays(current, -1);
        if (cal.compare(current) > 0) {
          System.out.println("Earliest day possible is yesterday");
          return false;
        }
        return cal.isValid();
      }
    }
    /**
     * Takes energyConsumed by a tower in a day split into 24 intervals.
     * @return double[] List of energy at each interval
     * @throws Exception if the method fails
     */
    public double[] trueRun() throws Exception {
      List<Source> sources = this.client.getSources();
      String sourceName;
      double energy;
      double[] baseArray = new double[24];
      XMLGregorianCalendar startDay = setStartDay();
      // Goes through all sources looking for the correct tower name.
      for (Source source : sources) {
        sourceName = source.getName();
        // Finds the correct tower name.
        if (sourceName.compareTo(this.tower) == 0) {
          // gets the energy consumed based on tower name and date.
          XMLGregorianCalendar endTime;
          for (int i = 1; i <= 24; i++) {
            //endTime is an hour after startDay
            endTime = Tstamp.incrementHours(startDay, 1);
            endTime = Tstamp.incrementSeconds(endTime, - 1);   
            //get the data
            energy = client.getEnergyConsumed(sourceName, startDay, endTime, 15);
            // add the corresponding data based on tower name and interval slot.
            baseArray[i - 1] = energy;
            //set the startday to endtime for next iteration
            endTime = Tstamp.incrementSeconds(endTime, 1);
            startDay = endTime;
          }
        }
      }
      startDay = Tstamp.incrementDays(startDay, -1);
      System.out.println("Set the baseline for " + tower + " with Timestamp " + startDay);
      //baseList.put(tower, baseArray);
      //System.out.println(baseList);
      return baseArray;
    }
    
    /**
     * Finds the start of a day.
     * Uses the date set if it's there or defaults to yesterday
     * @return XMLGregorianCalendar Tstamp for use later
     * @throws Exception if it fails
     */
    XMLGregorianCalendar setStartDay() throws Exception {
      XMLGregorianCalendar startDay;
      //if no date, use yesterday
      if (date == null) {
        startDay = Tstamp.makeTimestamp();
        startDay = Tstamp.incrementHours(startDay, - startDay.getHour());
        startDay = Tstamp.incrementMinutes(startDay, - startDay.getMinute());
        startDay = Tstamp.incrementSeconds(startDay, - startDay.getSecond());
        startDay = Tstamp.incrementDays(startDay, - 1);
      }
      //if not, use date
      else {
        startDay = Tstamp.makeTimestamp(date);
      }
      return startDay;
    }
  }